package demo.java.lang.management;

import com.alibaba.fastjson.JSON;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.management.AttributeNotFoundException;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanException;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.Query;
import javax.management.ReflectionException;
import java.lang.management.ClassLoadingMXBean;
import java.lang.management.CompilationMXBean;
import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryPoolMXBean;
import java.lang.management.MemoryType;
import java.lang.management.MemoryUsage;
import java.lang.management.OperatingSystemMXBean;
import java.lang.management.RuntimeMXBean;
import java.lang.management.ThreadMXBean;
import java.util.Arrays;
import java.util.List;
import java.util.Set;

public class ManagementFactoryDemo {

    private static Logger logger = LoggerFactory.getLogger(ManagementFactoryDemo.class);

    public static MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();
    public static RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
    public static ClassLoadingMXBean classLoadingMXBean = ManagementFactory.getClassLoadingMXBean();
    public static CompilationMXBean compilationMXBean = ManagementFactory.getCompilationMXBean();
    public static OperatingSystemMXBean operatingSystemMxBean = ManagementFactory.getOperatingSystemMXBean();
    public static ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
    public static List<MemoryPoolMXBean> memoryPoolMxBeanList = ManagementFactory.getMemoryPoolMXBeans();
    public static List<GarbageCollectorMXBean> garbageCollectorMXBeanList = ManagementFactory
            .getGarbageCollectorMXBeans();

    @Test
    public void testMemoryPoolMXBean() {
        List<MemoryPoolMXBean> list = ManagementFactory.getPlatformMXBeans(MemoryPoolMXBean.class);
        for (MemoryPoolMXBean bean : list) {
            print(bean);
            System.out.println();
        }
        System.out.println("-------------------------------------");
        List<MemoryPoolMXBean> memoryPoolMxBeanList = ManagementFactory.getMemoryPoolMXBeans();
        for (MemoryPoolMXBean bean : memoryPoolMxBeanList) {
            print(bean);
            System.out.println();
        }
    }

    public static void print(MemoryPoolMXBean bean) {
        String name = bean.getName();
        MemoryType memoryType = bean.getType();
        MemoryUsage usage = bean.getUsage();
        String[] memoryManagerNames = bean.getMemoryManagerNames();
        System.out.println(String.format("Name: %s，类型：%s，MemoryManagerNames：%s", name, memoryType, Arrays.toString(memoryManagerNames)));
        System.out.println(String.format("Usage：%s", usage));
    }

    @Test
    public void runtimeMXBeanDemo() {
        String name = runtimeMXBean.getName();
        System.out.println("name=" + name);
        System.out.println(JSON.toJSONString(runtimeMXBean));
    }

    @Test
    public void mbeanServer() {
        try {
            Set<ObjectName> set1 = mbeanServer.queryNames(new ObjectName("*:type=Connector,*"),
                    Query.match(Query.attr("protocol"), Query.value("HTTP/1.1")));
            for (ObjectName objectName : set1) {
                String port = objectName.getKeyProperty("port");
                logger.info("port:{}", port);
            }

            ObjectName threadpoolObjName = new ObjectName("Catalina:name=tomcatThreadPool,type=Executor");
            Set<ObjectName> set2 = mbeanServer.queryNames(threadpoolObjName, null);
            for (ObjectName obj : set2) {
                String canonicalName = obj.getCanonicalName();
                String name = obj.getKeyProperty("name");
                logger.info("canonicalName : {} , name:{}", canonicalName, name);

                ObjectName objname = new ObjectName(canonicalName);
                Object maxThreads = mbeanServer.getAttribute(objname, "maxThreads");
                Object queueSize = mbeanServer.getAttribute(objname, "queueSize");
                Object poolSize = mbeanServer.getAttribute(objname, "poolSize");
                Object activeCount = mbeanServer.getAttribute(objname, "activeCount");

                logger.info("maxThreads:{},queueSize:{},poolSize:{},activeCount:{}", maxThreads, queueSize, poolSize,
                        activeCount);
            }
        } catch (MalformedObjectNameException | InstanceNotFoundException | AttributeNotFoundException
                | ReflectionException | MBeanException e) {
            logger.error("", e);
        }
    }

}
